package com.jiawa.train.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiawa.train.business.domain.po.DailyTrainSeat;
import com.jiawa.train.business.domain.po.DailyTrainTicket;
import com.jiawa.train.business.domain.po.TrainStation;
import com.jiawa.train.business.enums.SeatTypeEnum;
import com.jiawa.train.business.enums.TrainTypeEnum;
import com.jiawa.train.business.mapper.DailyTrainTicketMapper;
import com.jiawa.train.business.req.DailyTrainTicketQueryReq;
import com.jiawa.train.business.req.DailyTrainTicketSaveReq;
import com.jiawa.train.business.resp.DailyTrainTicketQueryResp;
import com.jiawa.train.business.service.IDailyTrainSeatService;
import com.jiawa.train.business.service.IDailyTrainTicketService;
import com.jiawa.train.business.service.ITrainStationService;
import com.jiawa.train.common.exception.BusinessException;
import com.jiawa.train.common.exception.BusinessExceptionEnum;
import com.jiawa.train.common.resp.PageResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 余票信息 服务实现类
 * </p>
 *
 * @author hrz
 * @since 2025-09-07
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DailyTrainTicketServiceImpl extends ServiceImpl<DailyTrainTicketMapper, DailyTrainTicket> implements IDailyTrainTicketService {


    private final ITrainStationService trainStationService;
    private final IDailyTrainSeatService dailyTrainSeatService;

    @Override
    public PageResp<DailyTrainTicketQueryResp> queryList(DailyTrainTicketQueryReq req) {
        Page<DailyTrainTicket> page = this.lambdaQuery()
                .eq(req.getDate()!=null,DailyTrainTicket::getDate, req.getDate())
                .eq(req.getTrainCode()!=null,DailyTrainTicket::getTrainCode, req.getTrainCode())
                .eq(req.getStart()!=null,DailyTrainTicket::getStart, req.getStart())
                .eq(req.getEnd()!=null,DailyTrainTicket::getEnd, req.getEnd())
                .orderByDesc(req.getDate()!=null,DailyTrainTicket::getDate)
                .orderByAsc(req.getTrainCode()!=null,DailyTrainTicket::getTrainCode)
                .page(new Page<>(req.getPage(), req.getSize()));
        List<DailyTrainTicket> records = page.getRecords();
        if(ObjectUtil.isEmpty(records)){
            PageResp<DailyTrainTicketQueryResp> r = new PageResp<>();
            r.setList(new ArrayList<>());
            r.setTotal(0L);
            return r;
        }
        List<DailyTrainTicketQueryResp> respList = BeanUtil.copyToList(records, DailyTrainTicketQueryResp.class);
        PageResp<DailyTrainTicketQueryResp> r = new PageResp<>();
        r.setList(respList);
        r.setTotal(page.getTotal());
        return r;
    }

    @Override
    public void delete(Long id) {
        if(ObjectUtil.isEmpty(id)){
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        }
        this.removeById(id);
    }

    @Override
    public void saveDailyTrainTicket(DailyTrainTicketSaveReq req) {
        //2.判断是否是更新
        DailyTrainTicket dailyTrainTicket = BeanUtil
                .copyProperties(req, DailyTrainTicket.class);
        if(ObjectUtil.isNotEmpty(req.getId())){
            //更新
            dailyTrainTicket.setUpdateTime(LocalDateTime.now());
            this.updateById(dailyTrainTicket);
        }else{
            //新增
            //1.唯一性确认
            DailyTrainTicket one = this.lambdaQuery()
                    .eq(DailyTrainTicket::getDate, req.getDate())
                    .eq(DailyTrainTicket::getTrainCode, req.getTrainCode())
                    .eq(DailyTrainTicket::getStart, req.getStart())
                    .one();
            if (ObjectUtil.isNotEmpty(one)|| one != null ) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_DAILY_TRAIN_TICKET_UNIQUE_ERROR);
            }
            dailyTrainTicket.setCreateTime(LocalDateTime.now());
            dailyTrainTicket.setUpdateTime(LocalDateTime.now());
            this.save(dailyTrainTicket);
        }
    }

    @Override
    public void genDaily(String type,Date date, String code) {
        //1.删除旧数据
        this.lambdaUpdate()
                .eq(DailyTrainTicket::getDate, date)
                .eq(DailyTrainTicket::getTrainCode, code)
                .remove();
        //2.查询所有改车次的所有途径车站
        List<TrainStation> list = trainStationService.lambdaQuery()
                .eq(TrainStation::getTrainCode, code)
                .orderByAsc(TrainStation::getIndex)
                .list();
        //3.查询车座信息
        HashMap<String,Integer> map = new HashMap<>();
        for (int i1 = 1; i1 <= 4; i1++) {
            Long count = dailyTrainSeatService.lambdaQuery()
                    .eq(DailyTrainSeat::getTrainCode, code)
                    .eq(DailyTrainSeat::getDate, date)
                    .eq(DailyTrainSeat::getSeatType,String.valueOf(i1))
                    .count();
            if(ObjectUtil.isNull(count) || ObjectUtil.isEmpty(count)|| count.equals(0L)){
                map.put(String.valueOf(i1),-1);
            }
            map.put(String.valueOf(i1),count.intValue());
        }
        //4.单向循环生成票的信息
        for (int i = 0; i < list.size(); i++) {
            TrainStation start = list.get(i);
            BigDecimal sumKM = BigDecimal.ZERO;
            for(int j = i + 1; j < list.size(); j++){
                TrainStation end = list.get(j);
                DailyTrainTicket dailyTrainTicket = new DailyTrainTicket();
                dailyTrainTicket.setDate(date);
                dailyTrainTicket.setTrainCode(code);
                dailyTrainTicket.setStart(start.getName());
                dailyTrainTicket.setStartPinyin(start.getNamePinyin());
                dailyTrainTicket.setStartTime(start.getOutTime());
                dailyTrainTicket.setStartIndex(start.getIndex());
                dailyTrainTicket.setEnd(end.getName());
                dailyTrainTicket.setEndPinyin(end.getNamePinyin());
                dailyTrainTicket.setEndTime(end.getInTime());
                dailyTrainTicket.setEndIndex(end.getIndex());
                //票价 = 总里程数 * 座位系数 * 车次类型系数
                BigDecimal allKM = sumKM.add(end.getKm());
                dailyTrainTicket.setYdz(map.get("1"));
                dailyTrainTicket.setYdzPrice(allKM.multiply(SeatTypeEnum.YDZ.getPrice())
                        .multiply(Objects.requireNonNull(TrainTypeEnum.getEnumByCode(type)).getPriceRate()));
                dailyTrainTicket.setEdz(map.get("2"));
                dailyTrainTicket.setEdzPrice(allKM.multiply(SeatTypeEnum.EDZ.getPrice())
                        .multiply(Objects.requireNonNull(TrainTypeEnum.getEnumByCode(type)).getPriceRate()));
                dailyTrainTicket.setRw(map.get("3"));
                dailyTrainTicket.setRwPrice(allKM.multiply(SeatTypeEnum.RW.getPrice())
                        .multiply(Objects.requireNonNull(TrainTypeEnum.getEnumByCode(type)).getPriceRate()));
                dailyTrainTicket.setYw(map.get("4"));
                dailyTrainTicket.setYwPrice(allKM.multiply(SeatTypeEnum.YW.getPrice())
                        .multiply(Objects.requireNonNull(TrainTypeEnum.getEnumByCode(type)).getPriceRate()));
                dailyTrainTicket.setCreateTime(LocalDateTime.now());
                dailyTrainTicket.setUpdateTime(LocalDateTime.now());
                this.save(dailyTrainTicket);
            }
        }
    }
}
